using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration.Provider;
using System.Web.UI.WebControls;
using System.Web;

namespace Bbq.Gallery
{
	public abstract class GalleryProvider : ProviderBase
	{
		/// <summary>
		/// Constructor
		/// </summary>
		protected GalleryProvider() { }

		/// <summary>
		/// Creates the album.
		/// </summary>
		/// <param name="album">The album.</param>
		public abstract bool CreateAlbum(GalleryAlbum parent, GalleryAlbum album);
		/// <summary>
		/// Deletes the album.
		/// </summary>
		/// <param name="album">The album.</param>
		public abstract void DeleteAlbum(GalleryAlbum album);
		/// <summary>
		/// Updates the album.
		/// </summary>
		/// <param name="album">The album.</param>
		public abstract void UpdateAlbum(GalleryAlbum album);
		/// <summary>
		/// Gets the child albums.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract GalleryAlbum[] GetChildAlbums(GalleryAlbum album);
		/// <summary>
		/// Gets the gallery items.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract GalleryItem[] GetGalleryItems(GalleryAlbum album);
		/// <summary>
		/// Gets the paged gallery items.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <param name="pageIndex">Index of the page.</param>
		/// <param name="pageSize">Size of the page.</param>
		/// <param name="order">The order.</param>
		/// <param name="ascending">if set to <c>true</c> [ascending].</param>
		/// <param name="itemsCount">The items count.</param>
		/// <returns></returns>
		public abstract GalleryItem[] GetPagedGalleryItems(GalleryAlbum album, int pageIndex, int pageSize, GalleryOrder order, out int itemsCount);
		/// <summary>
		/// Gets the gallery album info.
		/// </summary>
		/// <param name="album">The album.</param>
		public abstract void GetGalleryAlbumInfo(GalleryAlbum album);
		/// <summary>
		/// Gets the gallery album info.
		/// </summary>
		/// <param name="albumID">The album ID.</param>
		/// <returns></returns>
		public abstract GalleryAlbum GetGalleryAlbumInfo(string albumID);
		/// <summary>
		/// Gets the gallery items count.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract int GetGalleryItemsCount(GalleryAlbum album);
		/// <summary>
		/// Gets the highlight item.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract GalleryItem GetHighlightItem(GalleryAlbum album);

		/// <summary>
		/// Sets the highlight item.
		/// </summary>
		/// <param name="item">The item.</param>
		public abstract void SetHighlightItem(GalleryItem item);
		/// <summary>
		/// Gets the album path.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract GalleryAlbum[] GetPathToAlbum(GalleryAlbum album);

		/// <summary>
		/// Resolves the album link.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract string ResolveAlbumLink(GalleryAlbum album);
		/// <summary>
		/// Resolves the album thumbnail.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract string ResolveAlbumThumbnail(GalleryAlbum album);
		/// <summary>
		/// Resolves the item link.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract string ResolveItemLink(GalleryItem item);
		/// <summary>
		/// Resolves the item thumbnail.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract string ResolveItemThumbnail(GalleryItem item);
		/// <summary>
		/// Resolves the item download.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract string ResolveItemDownload(GalleryItem item);
		/// <summary>
		/// Resolves the item identity.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract string ResolveItemIdentity(GalleryItem item);
		/// <summary>
		/// Some provider can encrypt Item ID. This function will return the actual item identity
		/// </summary>
		/// <param name="itemID">The item ID.</param>
		/// <returns></returns>
		public abstract string GetActualItemIdentity(string itemID);
		/// <summary>
		/// Resolves the album identity.
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns></returns>
		public abstract string ResolveAlbumIdentity(GalleryAlbum album);
		/// <summary>
		/// Gets the actual album identity.
		/// </summary>
		/// <param name="albumID">The album ID.</param>
		/// <returns></returns>
		public abstract string GetActualAlbumIdentity(string albumID);
		/// <summary>
		/// Gets the root.
		/// </summary>
		/// <value>The root.</value>
		public abstract GalleryAlbumNode Root { get;}

		/// <summary>
		/// Determines whether [is root album] [the specified album].
		/// </summary>
		/// <param name="album">The album.</param>
		/// <returns>
		/// 	<c>true</c> if [is root album] [the specified album]; otherwise, <c>false</c>.
		/// </returns>
		public abstract bool IsRootAlbum(GalleryAlbum album);


		private static int _pagerTotal;
		/// <summary>
		/// Gets or sets the pager total.
		/// </summary>
		/// <value>The pager total.</value>
		public static int PagerTotal
		{
			get { return _pagerTotal; }
			set { _pagerTotal = value; }
		}

		private static long _thumbnailCompression;
		/// <summary>
		/// Gets or sets the thumbnail compression.
		/// </summary>
		/// <value>The thumbnail compression.</value>
		public static long ThumbnailCompression
		{
			get { return _thumbnailCompression; }
			set { _thumbnailCompression = value; }
		}

		private static int _galleryItemThumbnailX;
		/// <summary>
		/// Gets or sets the gallery item thumbnail X.
		/// </summary>
		/// <value>The gallery item thumbnail X.</value>
		public static int GalleryItemThumbnailX
		{
			get { return _galleryItemThumbnailX; }
			set { _galleryItemThumbnailX = value; }
		}

		private static int _galleryItemThumbnailY;
		/// <summary>
		/// Gets or sets the gallery item thumbnail Y.
		/// </summary>
		/// <value>The gallery item thumbnail Y.</value>
		public static int GalleryItemThumbnailY
		{
			get { return _galleryItemThumbnailY; }
			set { _galleryItemThumbnailY = value; }
		}

		private static int _galleryAlbumThumbnailX;

		/// <summary>
		/// Gets or sets the gallery album thumbnail X.
		/// </summary>
		/// <value>The gallery album thumbnail X.</value>
		public static int GalleryAlbumThumbnailX
		{
			get { return _galleryAlbumThumbnailX; }
			set { _galleryAlbumThumbnailX = value; }
		}

		private static int _galleryAlbumThumbnailY;

		/// <summary>
		/// Gets or sets the gallery album thumbnail Y.
		/// </summary>
		/// <value>The gallery album thumbnail Y.</value>
		public static int GalleryAlbumThumbnailY
		{
			get { return _galleryAlbumThumbnailY; }
			set { _galleryAlbumThumbnailY = value; }
		}


		private static string _galleryRootPath = null;
		/// <summary>
		/// Gets or sets the gallery root path.
		/// </summary>
		/// <value>The gallery root path.</value>
		public static string GalleryRootPath
		{
			get { return _galleryRootPath; }
			set { _galleryRootPath = value; }
		}

		private static string _templatePath = null;
		/// <summary>
		/// Gets or sets the template path.
		/// </summary>
		/// <value>The template path.</value>
		public static string TemplatePath
		{
			get { return _templatePath; }
			set { _templatePath = value; }
		}

		private static string _defaultTemplate = null;

		/// <summary>
		/// Gets or sets the default template.
		/// </summary>
		/// <value>The default template.</value>
		public static string DefaultTemplate
		{
			get { return _defaultTemplate; }
			set { _defaultTemplate = value; }
		}

		private static int _pageSize = 0;

		/// <summary>
		/// Gets or sets the size of the page.
		/// </summary>
		/// <value>The size of the page.</value>
		public static int PageSize
		{
			get { return _pageSize; }
			set { _pageSize = value; }
		}

		private static string _defaultAlbumThumbnail = null;

		/// <summary>
		/// Gets or sets the default album thumbnail.
		/// </summary>
		/// <value>The default album thumbnail.</value>
		public static string DefaultAlbumThumbnail
		{
			get { return _defaultAlbumThumbnail; }
			set { _defaultAlbumThumbnail = value; }
		}

        public abstract bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item);
		/// <summary>
		/// Creates the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		public abstract bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item, FileUpload fileUpload);
		/// <summary>
		/// Creates the gallery item.
		/// </summary>
		/// <param name="parentAlbum">The parent album.</param>
		/// <param name="item">The item.</param>
		/// <param name="fileUpload">The file upload.</param>
		/// <param name="isZipFile">if set to <c>true</c> [is zip file].</param>
		/// <returns></returns>
		public abstract bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item, FileUpload fileUpload, bool isZipFile);
		/// <summary>
		/// Deletes the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		public abstract void DeleteGalleryItem(GalleryItem item);
		/// <summary>
		/// Gets the next gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract GalleryItem GetNextGalleryItem(GalleryItem item);
		/// <summary>
		/// Gets the previous gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract GalleryItem GetPreviousGalleryItem(GalleryItem item);
		/// <summary>
		/// Gets the gallery item info.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public abstract GalleryItem GetGalleryItemInfo(GalleryItem item);

		/// <summary>
		/// Gets the gallery item info.
		/// </summary>
		/// <param name="itemID">The item ID.</param>
		/// <returns></returns>
		public abstract GalleryItem GetGalleryItemInfo(string itemID);
		/// <summary>
		/// Changes the name of the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="newName">The new name.</param>
		public abstract void UpdateGalleryItem(GalleryItem item, GalleryItem newItem);
		public abstract void UpdateGalleryAlbum(GalleryAlbum album, GalleryAlbum newAlbum);

        /// <summary>
        /// Sets the album ID.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <param name="id">The id.</param>
        public virtual void SetAlbumID(GalleryAlbum album, object id)
        {
            if (id.GetType().Equals(typeof(int)))
            {
                album.ID = (int)id;
            }
        }
		/// <summary>
		/// Detects the type of the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		protected GalleryItemType DetectGalleryItemType(string extension)
		{
			extension = string.Concat("|", extension, "|");
			if (IsInFileTypes("|bmp|emf|gif|ico|jpg|jpeg|jpe|jfif|png|tif|tiff|wmf|", extension))
				return GalleryItemType.Picture;
			//Media Playlist: asx, wax, m3u, wpl, wvx, wmx
			//Microsoft Recorded TV Show: dvr-ms
			//MIDI file: mid, rmi, midi
			//Movie file (mpeg): mpeg, mpg, m1v, mp2, mpa, mp3, ifo, vob
			//Windows audio file (wav): wav, snd, au, aif, aifc, aiff, wma, mp3
			//Windows audio file (asf): asf, wm, wma, wmv, wmd
			//Windows video file (avi): avi, wmv
			else if (IsInFileTypes("|asx|wax|m3u|wpl|wvx|wmx|dvr-ms|mid|rmi|midi|mpeg|mpg|m1v|mp2|mpa|mpe|ifo|vob|wav|snd|au|aif|aifc|aiff|wma|mp3|asf|wm|wmd|avi|wmv|", extension))
				return GalleryItemType.CompatibleMediaPlayer;
			else if (IsInFileTypes("|swf|", extension))
				return GalleryItemType.CompatibleFlash;
			//This type is set by manual only.
			//else if ("".IndexOf(extension, StringComparison.OrdinalIgnoreCase))
			//    item.Type = GalleryItemType.Media;
			else if (IsInFileTypes("|rm|ram|ra|rpm|rv|", extension))
				return GalleryItemType.CompatibleRealPlayer;
			else if (IsInFileTypes("|mov|qt|m4p|qtif|qti|qtf|", extension))
				return GalleryItemType.CompatibleQuickTime;
			else
				return GalleryItemType.Archives;
		}

		/// <summary>
		/// Determines whether [is in file types] [the specified file types].
		/// </summary>
		/// <param name="fileTypes">The file types.</param>
		/// <param name="extension">The extension. It must start by '|' and end by '|'.</param>
		/// <returns>
		/// 	<c>true</c> if [is in file types] [the specified file types]; otherwise, <c>false</c>.
		/// </returns>
		private bool IsInFileTypes(string fileTypes, string extension)
		{
			return fileTypes.IndexOf(extension, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		/// <summary>
		/// Gets the type of the content (MIME)
		/// </summary>
		/// <param name="extension">The extension.</param>
		/// <returns></returns>
		internal string GetContentType(string extension)
		{
			switch (extension.ToLower())
			{
				case "jpg":
				case "jpeg":
				case "jpe":
					return "image/jpeg";
				case "gif":
					return "image/gif";
				case "bmp":
					return "image/bmp";
				case "tif":
				case "tiff":
					return "image/tiff";
				case "wmf":
					return "application/x-msmetafile";
				case "png":
					return "image/png";
				case "emf":
					return "image/emf";
				case "ico":
					return "image/x-icon";
				case "jfif":
					return "image/pipeg";
				//Flash
				case "swf":
					return "application/x-shockwave-flash";
				//Media
				case "asx":
					return "video/x-ms-asx";
				case "asf":
					return "video/x-ms-asf";
				case "wax":
					return "audio/x-ms-wax";
				case "m3u":
					return "audio/x-mpegurl";
				case "wpl":
					return "application/vnd.ms-wpl";
				case "wvx":
					return "video/x-ms-wvx";
				case "wmx":
					return "video/x-ms-wmx";
				case "dvr-ms":
					return "video/x-ms-dvr";
				case "mid":
				case "midi":
				case "rmi":
					return "audio/mid";
				case "mpeg":
				case "mpg":
				case "m1v":
				case "mp2":
				case "mpa":
				case "mpe":
				case "ifo":
				case "vob":
					return "video/mpeg";
				case "wav":
					return "audio/wav";
				case "snd":
				case "au":
					return "audio/basic";
				case "aif":
				case "aifc":
				case "aiff":
					return "audio/aiff";
				case "wma":
					return "audio/x-ms-wma";
				case "mp3":
					return "audio/mpeg";
				case "wm":
					return "video/x-ms-wm";
				case "wmd":
					return "application/x-ms-wmd";
				case "avi":
					return "video/avi";
				case "wmv":
					return "video/x-ms-wmv";
				//QuickTime video
				case "mov":
				case "qt":
				case "m4p":
					return "video/quicktime";
				//QuickTime image
				case "qtif":
				case "qti":
				case "qtf":
					return "image/quicktime";
				//RealMedia File
				case "rm":
					return "application/vnd.rn-realmedia";
				//RealAudio File
				case "ra":
				case "ram":
					return "audio/x-pn-realaudio";  //audio/vnd.rn-realaudio
				//RealVideo File
				case "rv":
					return "video/vnd.rn-realvideo";
				//RealAudio File
				case "rpm":
					return "audio/x-pn-realaudio-plugin";
				default:
					return "application/octet-stream";
			}
        }

        #region Import/Export functions
        /// <summary>
        /// Begins the import.
        /// </summary>
        /// <param name="parentAlbum">The parent album.</param>
        public virtual void BeginImport(GalleryAlbum parentAlbum)
        {
        }

        /// <summary>
        /// Commits the import.
        /// </summary>
        public virtual void CommitImport()
        {
        }

        /// <summary>
        /// Clears the items.
        /// </summary>
        public virtual void ClearItems4Importing()
        {
        }

        /// <summary>
        /// Inserts the import entry.
        /// </summary>
        /// <param name="item">The item.</param>
        public virtual void InsertImportEntry(GalleryItem item)
        {
        }
        #endregion
    }

	/// <summary>
	/// If we don't specify clearly, default is sort by asscending
	/// </summary>
	[Flags]
	public enum GalleryOrder
	{
		/// <summary>
		/// 
		/// </summary>
		None = 1,
		/// <summary>
		/// 
		/// </summary>
		Name = 2,
		/// <summary>
		/// 
		/// </summary>
		CreatedDate = 4,

		/// <summary>
		/// 
		/// </summary>
		LastModifiedDate = 8,
		/// <summary>
		/// 
		/// </summary>
		Vote = 16,
		/// <summary>
		/// Sort by asscending
		/// </summary>
		Deasscending = 1 << 31,

        CreatedDateDesc = CreatedDate | Deasscending,
        LastModifiedDateDesc = LastModifiedDate | Deasscending,
        NameDesc = Name | Deasscending
	}
}
